package http;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class OKHttpImpl implements IHttp {
	
	private HttpCallBack httpCallBack;
	
	public void setHttpCallBack(HttpCallBack httpCallBack) {
		this.httpCallBack=httpCallBack;
	}
	
	public interface HttpCallBack{
		void success(Map<Integer,String> map);
		void error(Map<Integer,String> map);
	}
	
	private Request.Builder requestBuilder;
	
	public OKHttpImpl() {
		requestBuilder=new Request.Builder();
	}

	@Override
	public Map<Integer,String> get(String path) throws IOException {
		long start=System.currentTimeMillis();
		Map<Integer,String> map=new HashMap<>();
		OkHttpClient client = new OkHttpClient();
		Request request = requestBuilder
	            .url(path)
	            .build();
		Response response = client.newCall(request).execute();
		long end=System.currentTimeMillis();
		map.put(1, response.body().string());
		Headers headers=response.headers();
		map.put(2,headers(headers));
		int code=response.code();
		long cost=end-start;
		map.put(3,code+"");
		map.put(4,cost+"");
		map.put(5,requestStr(request));
		return map;
	}
	
	public void setHeader(String headName,String headValue) {
		requestBuilder=requestBuilder.addHeader(headName, headValue);
	}
	
	private String headers(Headers headers) {
		int size=headers.size();
		StringBuilder sb=new StringBuilder();
		for(int i=0;i<size;i++) {
			sb.append(headers.name(i));
			sb.append(":");
			sb.append(headers.value(i));
			sb.append("\r\n");
		}
		return sb.toString();
	}
	
	private String requestStr(Request request) {
		StringBuilder sb=new StringBuilder();
		sb.append("Host:");
		sb.append(request.url().host());
		sb.append("\r\n");
		sb.append("Path:");
		sb.append(request.url().encodedPath());
		sb.append("\r\n");
		String query=request.url().encodedQuery();
		if(query!=null && query.length()>0) {
			sb.append("Path:");
			sb.append(request.url().encodedQuery());
			sb.append("\r\n");
		}
		sb.append("method:");
		sb.append(request.method());
		sb.append("\r\n");
		sb.append(headers(request.headers()));
		sb.append(request.cacheControl().toString());
		return sb.toString();
	}

	@Override
	public void getEnqueue(String path) throws IOException {
		// TODO Auto-generated method stub
		long start=System.currentTimeMillis();
		Map<Integer,String> map=new HashMap<>();
		OkHttpClient client = new OkHttpClient();
		Request request = requestBuilder
	            .url(path)
	            .build();
		client.newCall(request).enqueue(new Callback() {
			
			@Override
			public void onResponse(Call call, Response response) throws IOException {
				long end=System.currentTimeMillis();
				map.put(1, response.body().string());
				Headers headers=response.headers();
				map.put(2,headers(headers));
				int code=response.code();
				long cost=end-start;
				map.put(3,code+"");
				map.put(4,cost+"");
				map.put(5,requestStr(request));
				
				httpCallBack.success(map);
				
			}
			
			@Override
			public void onFailure(Call call, IOException e) {
				// TODO Auto-generated method stub
				long end=System.currentTimeMillis();
				map.put(1, e.getLocalizedMessage());
				map.put(2,"");
				int code=50;
				long cost=end-start;
				map.put(3,code+"");
				map.put(4,cost+"");
				map.put(5,requestStr(request));
				
				httpCallBack.error(map);
				
			}
		});
	}
	
	
	public void postString(String path) throws IOException {
		final MediaType MEDIA_TYPE_MARKDOWN
		  = MediaType.parse("text/x-markdown; charset=utf-8");
		
		OkHttpClient client = new OkHttpClient();
		String postBody = ""
		        + "Releases\n"
		        + "--------\n"
		        + "\n"
		        + " * _1.0_ May 6, 2013\n"
		        + " * _1.1_ June 15, 2013\n"
		        + " * _1.2_ August 11, 2013\n";
		Request request = new Request.Builder()
		        .url("https://api.github.com/markdown/raw")
		        .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody))
		        .build();
		 
		    Response response = client.newCall(request).execute();

		    System.out.println(response.body().string());
	}

}
